<?php
/**
 * Created by PhpStorm.
 * User: lhl
 * Date: 2019/5/20
 * Time: 16:55
 * Features: 基础自定义异常处理接管抽象类
 */

namespace app\common\exception;

use app\common\traits\CommonServiceTrait;
use think\exception\Handle;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Request;
use Exception;

header("Access-Control-Allow-Origin: *" );
header("Access-Control-Allow-Methods:GET,POST,OPTIONS,PATCH,PUT,DELETE");
header('Access-Control-Allow-Headers:accesstoken, permissiontoken, Origin, X-Requested-With, Content-Type, Content-Length, Accept, Accept-Encoding');
header('Access-Control-Max-Age: 3600000');

abstract class ExceptionHandle extends Handle
{
    //自定义异常其他特殊处理方法,需要子类重写
    const CUSTOM_EXCEPTION_METHOD = 'customExceptionHook';

    use CommonServiceTrait;

    /**
     * 子类必须实现jsonOutPut方法
    */
    abstract public function jsonOutPut();

    /**
     * 重写系统异常处理方法
    */
    public function render(Exception $e)
    {
        //如果是options请求,则响应固定数据
        if(Request::isOptions()){
            $this->setError($this->CODE_SUCCESS,'Options请求');
            return $this->jsonOutPut();
        }

        //异常状态码
        $apiStatusCode = self::getApiStatusCode();
        //属于验证器异常,捕获异常并返回提示信息
        if ($e instanceof ValidateException) {
            $this->setError($apiStatusCode['validate_error'],$e->getMessage());
            return $this->jsonOutPut();
        }

        //如果是主动抛出的自定义异常,则返回对应的json数据
        if($e instanceof CustomException){
            $this->setError($e->getCode(),$e->getMessage());
            //执行其他异常处理方法,比如记录后台日志
            $method = self::CUSTOM_EXCEPTION_METHOD;
            if(method_exists($this,$method)){
                $this->$method();
            }
            return $this->jsonOutPut();
        }

        //其他错误交给系统处理
        return parent::render($e);
    }

    /**
     * 获取异常状态码
    */
    public static function getApiStatusCode(){
        return Config::get('exception.api_status_code',[
            //服务器异常
            'server_error' => 0,
            //验证器异常
            'validate_error' => 0,
        ]);
    }
}